package com.yangff.service.impl;



import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yangff.api.client.UserClient;
import com.yangff.entity.product.entity.Financialproduct;
import com.yangff.entity.product.entity.Fundnetvalue;
import com.yangff.entity.product.entity.dto.FundnetvalueDTO;
import com.yangff.entity.user.entity.dto.UserAssetDTO;
import com.yangff.entity.user.entity.vo.UserAssetVo;
import com.yangff.mapper.FundnetvalueMapper;
import com.yangff.service.IFinancialproductService;
import com.yangff.service.IFundnetvalueService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yangff.utils.StockUtil;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 存储基金每日净值信息 服务实现类
 * </p>
 *
 * @author yangff
 * @since 2025-01-15
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class FundnetvalueServiceImpl extends ServiceImpl<FundnetvalueMapper, Fundnetvalue> implements IFundnetvalueService {
    private final IFinancialproductService financialproductService;
    private final FundnetvalueMapper fundnetvalueMapper;
    private final UserClient userClient;



    @Transactional(rollbackFor = Exception.class)
    @Override
    public void ListFundNetValue(FundnetvalueDTO fundnetvaluedto) {
        Financialproduct financialproduct = financialproductService.getOne(new LambdaQueryWrapper<Financialproduct>().eq(Financialproduct::getCode,fundnetvaluedto.getCode()));
        Fundnetvalue fundnetvalue = BeanUtil.copyProperties(financialproduct, Fundnetvalue.class);
        //刚注册统一为第0天
        fundnetvalue.setListDate(0);
        fundnetvalue.setChangeRate(0.0);
        fundnetvalue.setNetValue(fundnetvaluedto.getNetValue());

        save(fundnetvalue);
    }


    //更新基金净值，同时更新相关用户持有资产的更新，涉及到分布式问题，需要解决
    @CacheEvict(value = "fundnetvalue", allEntries = true)
    @Scheduled(cron = "0 0/1 * * * ?")
    @GlobalTransactional(rollbackFor = Exception.class)
    @Override
    public void updateFundNetValue() {
        //获取所有基金的最新净值记录
        List<Fundnetvalue> fundnetvalues = fundnetvalueMapper.selectListFundNetValue();

        //使用util算出下一天的净值记录，保存到List中
        Double startValue = null;


        for(Fundnetvalue fundnetvalue:fundnetvalues)
        {

            //获取上一个净值记录
            startValue = fundnetvalue.getNetValue();

            fundnetvalue.setNetValue(StockUtil.generateStockNextPrices(fundnetvalue.getNetValue(), fundnetvalue.getMu(), fundnetvalue.getSigma()));
            fundnetvalue.setListDate(fundnetvalue.getListDate()+1);


            //设置每个基金变化率
            fundnetvalue.setChangeRate((fundnetvalue.getNetValue() - startValue) / startValue);

            //更新所有持有该基金的用户的资产变化
            List<UserAssetVo> userAssetVos = userClient.getUserAssetByCode(fundnetvalue.getCode());


            for(UserAssetVo userAssetVo:userAssetVos)
            {
                //更改每个用户的资产和显示变化率
                UserAssetDTO userAssetDTO = BeanUtil.copyProperties(userAssetVo, UserAssetDTO.class);

                userAssetDTO.setCode(fundnetvalue.getCode());

                userAssetDTO.setAmount(userAssetDTO.getAmount() + userAssetDTO.getAmount() * fundnetvalue.getChangeRate());

                userAssetDTO.setChangeRate((userAssetDTO.getAmount() / userAssetDTO.getSeedMoney()) - 1);

                //log.info("名字:{},资产:{}", userAssetVo.getName(),userAssetDTO.getAmount());

                //userClient.changeUserAssetAmount(userAssetDTO);
                userClient.updateUserAssetByCode(userAssetDTO);
            }





            fundnetvalue.setChangeRate(fundnetvalue.getChangeRate() / startValue);
            //为每个基金插入下一天的净值记录
            save(fundnetvalue);
        }

    }
}
